/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Recommender.Collarative_Filtering;

import DataModel.ArrDataModel;
import DataModel.MaTrixUser_Item;
import IO.ReadFile;
import Recommender.Covisited.MaTrixCovisited;
import Recommender.LSH.LSH;
import Recommender.PLSI.PLSI_Method;
import java.io.IOException;

/**
 *
 * @author tuyetphuong
 */
public class Collarative_filtering {
    public LSH lsh ;
    public PLSI_Method plsi;
    public MaTrixCovisited covisited;
    public void Init_CF(ArrDataModel arr) throws IOException
    {
        //LSH lsh = new LSH();
        lsh= new LSH();
        lsh.Init_LSH(arr);
        plsi = new PLSI_Method();
        plsi.Init_PLSI(arr);
        covisited = new MaTrixCovisited();
        covisited.Init_Covisited(arr);


    }
    public int GetPoint_CF_Standar(int u, int s, ArrDataModel arr, float h1, float h2, float h3) throws IOException
    {
        if( GetPoint_CF(u, s, arr, h1, h2, h3)>0.2)
        {
            return 1;
        }
        return 0;
    }
    public float GetPoint_CF(int u , int s , ArrDataModel arr, float h1 , float h2, float h3) throws IOException
    {
        float pointLSH=lsh.GetPointLSH(u, s, arr);
       float pointPLSI=plsi.GetPoint_PLSI(u, s, arr);
     //  covisited.Update(u, s, s, arr);
        float pointCovisited=covisited.GetPoint_Covisited(u, s, arr);
        float pointCF;
        pointCF= h1*pointLSH+h2*pointPLSI+h3*pointCovisited;

       // return pointCF;
    //  System.out.print(pointLSH);
      /* System.out.print("\n");
       System.out.print(pointPLSI);
       System.out.print("\n");
      System.out.print(pointCovisited);
       System.out.print("\n");*/
        return pointCF;
    }
   


    public float GetPoint_collarative_filtering(int u, int s, ArrDataModel arr,MaTrixUser_Item matrix,int[]Item , float[][] arrsim, MaTrixCovisited matrixcovisit ) {
       
        //ArrDataModel arr = new ArrDataModel();
        //ReadFile readfile = new ReadFile();
        //arr = readfile.ReadTrainFile("u6.base");
       // arr.GetNumOFItem();
        //arr.GetNumOFUser();
        //ArrDataModel arr1 = new ArrDataModel();
        //arr1 = readfile.ReadTestFile("u6.base");
        //arr1.GetNumOFItem();
       // arr1.GetNumOFUser();
      //  LSH lsh= new LSH();
        //lsh.numofhash = 100;
        //lsh.numofkeyhash = 30;
      //  MaTrixUser_Item matrix = new MaTrixUser_Item();
        //PLSI_Method plsi = new PLSI_Method();
        //matrix = arr.CreateMatrixUser_Item();
        //int[] Item = arr.GetItemSet();
      //  int[][] HashValue = lsh.ArrHash(Item, matrix, arr);
        //float[][]arrsim =lsh.ArrSim(HashValue, arr);
        //float[]Danhgiatrungbinh = lsh.DanhGiaTrungBinh(arr);
       // taptest = arr1.numofrow;
        //int[] KLangGieng = lsh.TimKLangGieng(u, 0, arrsim, arr);
        float pointLSH= lsh.PredictPoint(u, s, arr);
       // MaTrixCovisited matrixcovisit= new MaTrixCovisited();
       // matrixcovisit.CountCovisted(arr);
        float pointCovisited =matrixcovisit.GetPoint_Covisited(u, s, arr);
        plsi.Sodoituong=arr._MaxItem+1;
        plsi.Songuoidung=arr._MaxUser+1;
        plsi.Sonhom=30;
        float pointPLSI=plsi.psu(s, u, arr);
        float pointCollarative= (float) (0.3* pointCovisited + 0.6* pointLSH + 0.1 * pointPLSI);
        return pointCollarative;
       
       
    }
    public void Test() throws IOException
    {

        float f;
        int sotuvandung = 0;
        int sotuvan = 0;
        int sodanhgia = 0;
        int sodanhgiadung = 0;
        int taptest = 0;
        float recall = 0;
        float precsion = 0;
        float mae = 0;
        float rmse = 0;
        int solantuvanrecall = 0;
        int solantuvanprecsion = 0;
        ArrDataModel arr = new ArrDataModel();
        ReadFile readfile = new ReadFile();
        arr = readfile.ReadTrainFile("u6.base");
        arr.GetNumOFItem();
        arr.GetNumOFUser();
        PLSI_Method plsi = new PLSI_Method();
        plsi.Init_PLSI(arr);
        MaTrixCovisited co = new MaTrixCovisited();
        co.Init_Covisited(arr);
        ArrDataModel arr1 = new ArrDataModel();
        arr1 = readfile.TestFile20();
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();
        MaTrixUser_Item matrix = new MaTrixUser_Item();
        matrix = arr.CreateMatrixUser_Item();
        int[] Item = arr.GetItemSet();
         LSH lsh= new LSH();
         lsh.Init_LSH(arr);
        lsh.numofhash = 100;
        lsh.numofkeyhash = 30;
        MaTrixCovisited matrixcovisit= new MaTrixCovisited();
        matrixcovisit.CountCovisted(arr);
        int[][] HashValue = lsh.ArrHash(Item, matrix, arr);
        float[][]arrsim =lsh.ArrSim1(arr);
        taptest = arr1.numofrow;
         for (int i = 0; i < arr1.numofrow; i++) {

             System.out.print(GetPoint_collarative_filtering(arr1.arrmodel.get(i).GetIDUser(), arr1.arrmodel.get(i).GetIDItem(), arr, matrix, Item, arrsim, matrixcovisit));
             System.out.print("\n");
            if (GetPoint_collarative_filtering(arr1.arrmodel.get(i).GetIDUser(), arr1.arrmodel.get(i).GetIDItem(), arr, matrix, Item, arrsim, matrixcovisit)>0.25)
                     {
                sodanhgiadung++;
            }
        }
        float p = (float) 0.0;
        p = (taptest-sodanhgiadung);
        p = p / taptest;
        mae = p;
        System.out.print(mae);
        System.out.print("\n");
        p = (float) Math.sqrt(p);
        rmse = p;
        System.out.print(rmse);
        System.out.print("\n");
        p = (float) Math.sqrt(p);
        int[] itemset = arr1.GetItemSet();
        int[] userset = arr1.GetUserSet();
        for (int i = 0; i < userset.length; i++) {
            int[] taptuvan = new int[1000];
            sotuvan = 0;
            int[] ratingset = arr1.UserRating(userset[i]);
            for (int j = 0; j < itemset.length; j++) {
                if (GetPoint_collarative_filtering(arr1.arrmodel.get(i).GetIDUser(),
                        arr1.arrmodel.get(i).GetIDItem(), arr, matrix, Item, arrsim, matrixcovisit)>0.18){
                    taptuvan[sotuvan] = itemset[j];
                    sotuvan++;
                }
            }
            sotuvandung = 0;
            for (int ii = 0; ii < ratingset.length; ii++) {
                for (int j = 0; j < sotuvan; j++) {
                    if (ratingset[ii] == taptuvan[j]) {
                        sotuvandung++;
                    }
                }
            }
            if (ratingset.length != 0) {
                recall += (float) sotuvandung / (float) ratingset.length;
                solantuvanrecall++;
            }
            if(sotuvan!=0)
            {
                precsion+=(float)sotuvandung/(float)sotuvan;
                solantuvanprecsion++;
            }
        }
        recall = (float) recall / (float) solantuvanrecall;
        System.out.print(recall);
        System.out.print("\n");
        precsion = (float) precsion / (float) solantuvanprecsion;
        System.out.print(precsion);
        System.out.print("\n");
        f=2*recall*precsion / (recall+precsion);
        System.out.print(f);
        System.out.print("\n");
    }
    public void TestCF(ArrDataModel arr, ArrDataModel arr1) throws IOException
    {
       /* ReadFile read= new ReadFile();
        arr=read.ReadTrainFile("pp");
        arr1=read.TestFile();
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();*/
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();
        Collarative_filtering cf= new Collarative_filtering();
        cf.Init_CF(arr);
        int sodanhgiadung=0;
        for( int i =0;i<arr1.numofrow;i++)
        {
            if(cf.GetPoint_CF_Standar(arr1.arrmodel.get(i).GetIDUser(),
                    arr1.arrmodel.get(i).GetIDItem(), arr, (float)0.4, (float)0.3, (float)0.3)==arr1.arrmodel.get(i).GetRating())
            {
                sodanhgiadung++;
            }
        }
        float mae=0;
        float p = (arr1.numofrow-sodanhgiadung);
        p = p / arr1.numofrow;
        mae = p;
        System.out.print(mae);
        System.out.print("\n");
        float rmse=0;
        p = (float) Math.sqrt(p);
        rmse = p;
        System.out.print(rmse);
        System.out.print("\n");


    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        Collarative_filtering cf= new Collarative_filtering();
        ReadFile r = new ReadFile();
        ArrDataModel arr= new ArrDataModel();
        arr=r.ReadTrainFile("pp");
        cf.Init_CF(arr);
        ArrDataModel arr1= new ArrDataModel();
        arr1=r.TestFile();
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();
        cf.TestCF(arr, arr1);

        //cf.GetPoint_CF(1, 1, arr, (float)0.4, (float)0.3, (float)0.3);


        }
        
       
    
}
